package com.after.saas.common.aspect;

import com.after.saas.common.annotation.NoRepeatSubmit;
import com.after.saas.common.exception.BizException;
import com.after.saas.common.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

/**
 * @Classname RepeatSubmitAspect
 * @Description TODO
 * @Date 2021/5/18 11:30
 * @Created by hjchen
 */

@Slf4j
@Aspect
@Component
public class RepeatSubmitAspect {

    @Autowired
    private RedisTemplate redisTemplate;

    @Around("@annotation(nrs)")
    public Object around(ProceedingJoinPoint pjp, NoRepeatSubmit nrs) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        assert attributes != null;
        String sessionId = attributes.getSessionId();
        HttpServletRequest request = attributes.getRequest();
        String key = RedisUtil.redisCommonKey(request.getRequestURI(), sessionId);
        if (RedisUtil.hasKey(redisTemplate, key)) {// 如果缓存中有这个url视为重复提交
            log.warn("操作太频繁，请勿重复提交 {}", key);
            throw new BizException("操作太频繁，请勿重复提交");
        } else {
            try {
                Object o = pjp.proceed();
                RedisUtil.storeObject(redisTemplate, key, 0, nrs.timeout(), TimeUnit.SECONDS);
                return o;
            } catch (Throwable throwable) {
                throwable.printStackTrace();
                log.error("重复请求校验失败,删除key {}", RedisUtil.deleteKey(redisTemplate, key));
                throw new BizException("重复请求校验失败！");
            }
        }
    }
}